#pragma once

#include "tcp_socket.h"  // 引入 TCPSocket，间接依赖 socket_utils/logging 等模块。

namespace Common {
  /**
   * @brief TCPServer 封装：管理监听 socket、epoll 事件、连接集合与回调。
   *
   * Logger 在整个服务器生命周期中同步输出事件，以便通过异步日志线程分析连接状态。
   */
  struct TCPServer {
    explicit TCPServer(Logger &logger)
        : listener_socket_(logger), logger_(logger) {
    }

    /**
     * @brief 在指定接口/端口上启动监听。
     *
     * @param iface 网络接口名（如 "eth0"）。
     * @param port  监听端口。
     *
     * @note 内部创建 epoll fd 并将监听 socket 加入事件列表。
     */
    auto listen(const std::string &iface, int port) -> void;

    /**
     * @brief 轮询 epoll 事件，维护 socket 容器。
     *
     * @note 将新连接/可读/可写的 socket 添加到 receive/send 队列，并在日志中记录。
     */
    auto poll() noexcept -> void;

    /**
     * @brief 将所有收发 socket 执行一次 sendAndRecv()。
     *
     * @note
     *  - 若任一 socket 有数据到达，会触发 recv_callback_，并在全部处理完毕后
     *    调用 recv_finished_callback_ 通知监听者。
     */
    auto sendAndRecv() noexcept -> void;

  private:
    /**
     * @brief 将 socket 添加到 epoll 列表（边缘触发 + EPOLLIN）。
     *
     * @param socket 待添加的 TCPSocket。
     * @return 成功返回 true（内部使用 epoll_ctl）。
     */
    auto addToEpollList(TCPSocket *socket);

  public:
    /// epoll 文件描述符，listen() 成功后有效。
    int epoll_fd_ = -1;

    /// 监听 socket（包含 Logger 引用，复用 TCPSocket 的封装逻辑）。
    TCPSocket listener_socket_;

    /// epoll 返回的事件数组，容量固定 1024。
    epoll_event events_[1024];

    /// 当前处于可读状态的 socket 集合。
    std::vector<TCPSocket *> receive_sockets_;
    /// 当前需要发送数据的 socket 集合。
    std::vector<TCPSocket *> send_sockets_;

    /// 收到数据时触发的回调，由外部设置。
    std::function<void(TCPSocket *s, Nanos rx_time)> recv_callback_ = nullptr;
    /// 一轮收发循环结束后的回调。
    std::function<void()> recv_finished_callback_ = nullptr;

    /// 辅助 Logger 输出时间戳。
    std::string time_str_;

    /// 全局 Logger 引用，用于记录所有服务器事件。
    Logger &logger_;
  };
}  // namespace Common